package pfc.aviloc.aplicacion.medicamentos;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

import org.xml.sax.InputSource;

import pfc.aviloc.R;
import pfc.aviloc.comunicacion.Comunicacion;
import pfc.aviloc.configuracion.ConfiguracionPreferenceActivity;

import android.R.integer;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;

public class MedicamentoCrearAlarmService extends Service {

	@Override
	public IBinder onBind(Intent arg0) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void onCreate() {
		super.onCreate();
		if (comprobarAlarmaActiva()){
			ArrayList<Medicamentos> listaMedicamentos;
			if (comprobarServidor() && comprobarResgistroUsuario() && comprobarConexion()) {			
				// recuperamos los datos del servidor. 
				listaMedicamentos = obtenerMedicamentosServidor();			
				if (listaMedicamentos!=null){
					// almacenamos los datos. 
					boolean correcto = guardarMedicamentosBD(listaMedicamentos);
				} else {
					// recuperamos los ultimos datos almacenados
					listaMedicamentos = obtenerMedicamentosBD();
				} 
			} else {
				// recuperamos los ultimos datos almacenados
				listaMedicamentos = obtenerMedicamentosBD();
			}
			crearAlarma(listaMedicamentos);
		} else {
			quitarAlarma();
		}
		
		stopSelf();
	}

	private void quitarAlarma() {
		final int ALARM_REQUEST_CODE = 1;
		Intent intent = new Intent(this, MedicamentoAlarmActivity.class);
		intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		PendingIntent pendingIntent = PendingIntent.getActivity(this, ALARM_REQUEST_CODE, intent, PendingIntent.FLAG_ONE_SHOT);
		AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
		alarmManager.cancel(pendingIntent);	
        pendingIntent = null;
	}

	public boolean crearAlarma(ArrayList<Medicamentos> listaMedicamentos){
		final int ALARM_REQUEST_CODE = 1;

		Intent intent = new Intent(this, MedicamentoAlarmActivity.class);
		intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		PendingIntent pendingIntent = PendingIntent.getActivity(this, ALARM_REQUEST_CODE, intent, PendingIntent.FLAG_ONE_SHOT);
		
		long milliProximaAlarm = getHoraProximaAlarm(listaMedicamentos);
		Calendar cal = Calendar.getInstance();
		cal.setTimeInMillis(System.currentTimeMillis()+milliProximaAlarm);
		AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
		alarmManager.cancel(pendingIntent);
		alarmManager.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent);
	
		long ahora= Calendar.getInstance().getTimeInMillis();
		Log.i("INFO","<<*******<< MilliSegudonsAhora :"+ahora);
		Log.i("INFO","<<*******<< MilliSegundosAlarma:"+cal.getTimeInMillis());
		Log.i("INFO","<<*******<< Diferencia:"+((cal.getTimeInMillis()-ahora)/1000)+" segundos");
		return true;
	}
	
	private long getHoraProximaAlarm(ArrayList<Medicamentos> listaMedicamentos) {
		Calendar cal = Calendar.getInstance();
		cal.setTimeInMillis(System.currentTimeMillis());
		int horaActual = cal.get(Calendar.HOUR_OF_DAY);
		int minActual = cal.get(Calendar.MINUTE);
		String horaTomaDesayuno = ConfiguracionPreferenceActivity.getHoraTomaDesayuno(this);
		String horaTomaComida = ConfiguracionPreferenceActivity.getHoraTomaComida(this);
		String horaTomaMerienda = ConfiguracionPreferenceActivity.getHoraTomaMerienda(this);
		String horaTomaCena = ConfiguracionPreferenceActivity.getHoraTomaCena(this);
		String horaTomaDormir = ConfiguracionPreferenceActivity.getHoraTomaAcostarse(this);
		if (getHora(horaTomaDormir)<10 ){
			horaTomaDormir = ""+(getHora(horaTomaDormir)+24);
		}
		long milliSecDesayuno = ((getHora(horaTomaDesayuno)-horaActual)*3600000)+((getMinuto(horaTomaDesayuno)-minActual)*60000); 
		long milliSecComida = ((getHora(horaTomaComida)-horaActual)*3600000)+((getMinuto(horaTomaComida)-minActual)*60000);
		long milliSecMerienda = ((getHora(horaTomaMerienda)-horaActual)*3600000)+((getMinuto(horaTomaMerienda)-minActual)*60000);
		long milliSecCena = ((getHora(horaTomaCena)-horaActual)*3600000)+((getMinuto(horaTomaCena)-minActual)*60000);
		long milliSecDormir = ((getHora(horaTomaDormir)-horaActual)*3600000)+((getMinuto(horaTomaDormir)-minActual)*60000);

		boolean activarAlarmaDesayuno = false;
		boolean activarAlarmaComida = false;
		boolean activarAlarmaMerienda = false;
		boolean activarAlarmaCena = false;
		boolean activarAlarmaDormir = false;		

		for (Medicamentos medicamento : listaMedicamentos) {
			int frecuencia = new Integer(medicamento.getFrecuencia());
			switch (frecuencia) {
			case 1:
				activarAlarmaComida = true; // TODO elegir el correcto
				break;
			case 2:
				activarAlarmaDesayuno = true;
				activarAlarmaCena = true;
				break;
			case 3:
				activarAlarmaDesayuno = true;
				activarAlarmaComida = true;
				activarAlarmaCena = true;
				break;
			case 4:
				activarAlarmaDesayuno = true;
				activarAlarmaComida = true;
				activarAlarmaMerienda = true;
				activarAlarmaDormir = true;
				break;
			default:
				break;
			}
		}
		if (activarAlarmaDesayuno || activarAlarmaComida || activarAlarmaMerienda || activarAlarmaCena || activarAlarmaDormir ) {
			if (activarAlarmaDesayuno && milliSecDesayuno>0 && (milliSecDesayuno<milliSecComida && milliSecDesayuno<milliSecMerienda && milliSecDesayuno<milliSecCena && milliSecDesayuno<milliSecDormir) ){
				return milliSecDesayuno;
			} else if (activarAlarmaComida && milliSecComida>0 && (milliSecComida<milliSecMerienda && milliSecComida<milliSecCena && milliSecComida<milliSecDormir) ){
				return milliSecComida;
			} else if (activarAlarmaMerienda && milliSecMerienda>0 && ( milliSecMerienda<milliSecCena && milliSecMerienda<milliSecDormir) ){
				return milliSecMerienda;
			} else if (activarAlarmaCena && milliSecCena>0 && ( milliSecCena<milliSecDormir) ){
				return milliSecCena;
			} else if (activarAlarmaDormir && milliSecDormir>0 ){
				return milliSecDormir;
			} else if (activarAlarmaDesayuno){
				milliSecDesayuno = milliSecDesayuno + (24*3600000);				
				return milliSecDesayuno;
			} else if (activarAlarmaComida){
				milliSecComida = milliSecComida + (24*3600000);
				return milliSecComida;
			} else if (activarAlarmaMerienda){
				milliSecMerienda = milliSecMerienda + (24*3600000);
				return milliSecMerienda;
			} else if (activarAlarmaCena) {
				milliSecCena = milliSecCena + (24*3600000);					
				return milliSecCena;
			} else {
				milliSecDormir = milliSecDormir + (24*3600000);
				return milliSecDormir;
			}			
		} else {
			return -1;
		}
	}
	private int getHora(String horaToma) {
		int posDosPuntos = horaToma.indexOf(":");
		int hora = Integer.valueOf(horaToma.substring(0, posDosPuntos));
		return hora;
	}
	private int getMinuto(String horaToma) {
		int posDosPuntos = horaToma.indexOf(":");
		int minuto = Integer.valueOf(horaToma.substring(posDosPuntos+1, horaToma.length()));
		return minuto;
	}
	 
	private ArrayList<Medicamentos> obtenerMedicamentosBD(){
		MedicamentosBD mBD = new MedicamentosBD(this, this.getString(R.string.m_bd_nombre_base_datos), null, this.getResources().getInteger(R.integer.m_bd_version));
		ArrayList<Medicamentos> listaMedicamentos = mBD.recuperarBD();
		
		return listaMedicamentos;
	}
	
	private boolean guardarMedicamentosBD(ArrayList<Medicamentos> listaMedicamentos){		
		
	 	MedicamentosBD mBD = new MedicamentosBD(this, this.getString(R.string.m_bd_nombre_base_datos), null, this.getResources().getInteger(R.integer.m_bd_version));
	 
	 	boolean  correcto = true;
	 	boolean insertado = false;
	 	for (Medicamentos medicamento : listaMedicamentos) {	
	 		insertado = mBD.insertarBD(medicamento);			
	 		correcto = correcto && insertado;	 		
		}				
		return correcto;		
	}
	
	private ArrayList<Medicamentos> obtenerMedicamentosServidor(){
		
		ArrayList<Medicamentos> returnDatos = null;

  		InputSource respuestaXMLInputSource = null;
		
		try {
			Map<String, String> kvParameters = new HashMap<String, String>();
			String key = getString(R.string.m_clave_param_idUsuario);
			String valor = ConfiguracionPreferenceActivity.getIdUsuario(this);
			kvParameters.put(key, valor);	
			
			String url = ConfiguracionPreferenceActivity.getDireccionServidor(this)+ getString(R.string.m_url_medicamentos);
			
			// llamamos al servidor por la url y pasandole el id del usuario: recibiendo un inputsource para parsear.
			respuestaXMLInputSource = Comunicacion.getXML(url, kvParameters);
			
			MedicamentosParseador  mParseador = new MedicamentosParseador(this);
			returnDatos = mParseador.getMedicamentos(respuestaXMLInputSource);
			
			if (returnDatos == null) {
				boolean error = mParseador.error;
				String tipoError = mParseador.tipoError;
			}
			mParseador = null;
		} catch (Exception e) {
			returnDatos = null;
		}
		return returnDatos;
	}	
	
	private boolean comprobarConexion() {	
		String urlString = ConfiguracionPreferenceActivity.getDireccionServidor(this);
		int timeOut = this.getResources().getInteger(R.integer.TIME_OUT_SINCRONISMO);
		try {
			return Comunicacion.doPing(urlString, timeOut);
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		}
	}
	
	private boolean comprobarServidor() {
		return ConfiguracionPreferenceActivity.isSincronismoServidor(this);
	}

	private boolean comprobarResgistroUsuario() {
		return ConfiguracionPreferenceActivity.isRegistroMovilEnServidor(this);
	}
	
	private boolean comprobarAlarmaActiva() {
		return ConfiguracionPreferenceActivity.isAlarmaCitasMedico(this);
	}
}
